package com.zwj.spring_study.a01;

import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;

/**
 * @author 张文接
 * @version 1.0
 * @createTime 2024/5/12 19:56
 */
@Slf4j
public class TestBeanFactory {

    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        //bean 的定义（class，scope，初始化，销毁）
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder
                .genericBeanDefinition(Config.class)//定义Bean的类型
                .setScope(BeanDefinition.SCOPE_SINGLETON)//设置Bean的作用域
                .getBeanDefinition();//获取BeanDefinition

        //注册上面定义的beanDefinition
        beanFactory.registerBeanDefinition("config", beanDefinition);
        //打印BeanFactory中的所有BeanDefinition 目前只有一个config
        for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }
        System.out.println("===========================================");
        //注册BeanPostProcessor  添加一些常用的Bean后置处理器
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
        //会发现多了5个Bean
        for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }
        System.out.println("===========================================");
        //补充Bean的定义  相当于使用了上面添加的Bean后置处理器
        beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().forEach(
                beanFactoryPostProcessor -> {
                    beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
                }
        );

        for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }

    }


    @Configuration
    static class Config {
        @Bean
        public Bean1 bean1() {
            return new Bean1();
        }

        @Bean
        public Bean2 bean2() {
            return new Bean2();
        }
    }

    static class Bean1 {
        private static final Logger log = LoggerFactory.getLogger(Bean1.class);

        public Bean1() {
            log.info("构造方法 Bean1（）");
        }
    }

    static class Bean2 {
        private static final Logger log = LoggerFactory.getLogger(Bean2.class);

        @Resource
        private Bean2 bean2;

        public Bean2() {
            log.info("构造方法 Bean2（）");
        }
    }
}
